#pragma once
#include<iostream>
#include<unistd.h>
#include<cstdio>
#include<cassert>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<cstring>
#include<cerrno>
#include<cstdlib>
#include<sys/stat.h>
#define PATH_NAME "."
#define PROJ_ID 0x67//只需要让getkey能够得出独特的key即可
#define MAX_SIZE 4096
key_t getkey()
{
    key_t ret = ftok(PATH_NAME,PROJ_ID);
    if(ret == -1)
    {
        std::cout<<"获取key错误"<<errno<<strerror(errno)<<std::endl;
        exit(2);
    }
    return ret;
}
int getshmHelper(key_t key,int flag)
{
    int id = shmget(key,MAX_SIZE,flag);
    if(id == -1)
    {
        std::cout<<"共享内存获取错误"<<errno<<strerror(errno)<<std::endl;
        exit(2);
    }
    return id;

}
int Create_shm(key_t key)
{
    return getshmHelper(key,IPC_CREAT | IPC_EXCL | 0666);
}
int Getshm(key_t key)
{
    return getshmHelper(key,IPC_CREAT);
}
void * attach(int shmid)
{
    void*mem = shmat(shmid,NULL,0);
    //改long long 的原因是因为系统是64位，返回的指针是8字节，强转为int只有4字节，有精度损失
    if((long long)mem == -1L)
    {
        std::cout<<"链接共享内存出错"<<strerror(errno)<<std::endl;
        exit(2);
    }
    std::cout<<"共享内存链接成功！"<<std::endl;
    sleep(3);
    return mem;
}
void dettach(void * start)
{
    int n = shmdt(start);
    if(n == -1)
    {
        std::cout<<"去关联失败"<<strerror(errno)<<std::endl;
        exit(2);
    }
    sleep(3);
    std::cout<<"共享内存去链接成功！"<<std::endl;
}
void Del_shm(int shmid)
{
    int id = shmctl(shmid,IPC_RMID,NULL);
    if(id== -1)
    {
        std::cerr<<"删除共享内存失败"<<errno<<strerror(errno)<<std::endl;
        exit(2);
    }
    std::cout<<"共享内存关闭成功"<<std::endl;
}